#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<map>
#include<set>
#include<unordered_set>
#include<bits/stdc++.h>
#define fi first
#define se second
#define SIZE(x) ((int)x.size())
#define out(x) cerr<<#x<<" = "<<(x)<<endl;
#define MP(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
#define VI vector<int>
#define VVI vector< vector<int> >
#define VC vector<char>
#define PI pair<int,int>
#define PL pair<ll,ll>
#define EPS 0.000001


inline int lson(int x){return x<<1;}
inline int rson(int x){return (x<<1)|1;}

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

template<typename T> 
inline void read(T &x){
	x=0;T f=1;char ch;
	do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
	do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
}


//#define INF 5340172838076674L
#define INF 1000000000
#define MOD 100003
struct node{
	ll a,b;
	bool operator<(const node& x)const{
		return a<x.a;
	};
};

struct no{
	ll a,b,c;
	bool operator<(const no& x)const{
		return c<x.c;
	}
};

#define maxn 100005
struct EDGE{
	int next,to,from;
}edg[maxn*10],ee[maxn*10];
int ecount=0,esum=0,n,m,tim;
int head[maxn];
int dfn[maxn],low[maxn],sd[maxn],p[maxn],h[maxn],in[maxn],vs[maxn];
bool vis[maxn];
stack<int> sta;
void add(int x,int y){
	//x->y
	edg[++ecount].next=head[x];
	head[x]=ecount;
	edg[ecount].to=y;
	edg[ecount].from=x;
}

void tarjan(int x){
	dfn[x]=low[x]=++tim;
	sta.push(x);vis[x]=true;
	for(int i=head[x];i;i=edg[i].next){
		int v=edg[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}else if(vis[v])low[x]=min(low[x],dfn[v]);
	}
	if(dfn[x]==low[x]){
		int tmp;
		while(!sta.empty()){
			tmp=sta.top();sta.pop();
			sd[tmp]=x;
			vis[tmp]=false;
			if(tmp==x)break;
			p[x]+=p[tmp];
		}
	}
}

int main(){
    #ifdef BUG
    freopen("a.in","r",stdin);
    #endif
	n=read();m=read();
	for(int i=1;i<=n;i++)p[i]=read();
	memset(edg,0,sizeof edg);
	memset(head,0,sizeof head);
	memset(dfn,0,sizeof dfn);
	memset(vis,0,sizeof vis);
	memset(ee,0,sizeof ee);
	memset(in,0,sizeof in);
	memset(vs,0,sizeof vs);
	memset(h,0,sizeof h);
	int a,b;
	for(int i=0;i<m;i++){
		a=read();b=read();
		add(a,b);
	}
	tim=0;
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
	
	for(int i=1;i<=ecount;i++){
		int y=sd[edg[i].to],x=sd[edg[i].from];
		if(x!=y){
			ee[++esum].next=h[x];
			h[x]=esum;
			ee[esum].to=y;ee[esum].from=x;
			++in[y];
		}
	}
	queue<int> q;
	for(int i=1;i<=n;i++)if(dfn[i]==low[i]&&in[i]==0){
		q.push(i);
		vs[i]=p[i];
	}
	while(!q.empty()){
		int tmp=q.front();q.pop();
		for(int i=h[tmp];i;i=ee[i].next){
			if(--in[ee[i].to]==0){q.push(ee[i].to);}//cout<<' '<<i<<endl;}
			vs[ee[i].to]=max(vs[ee[i].to],vs[tmp]+p[ee[i].to]);
		}
	}
	int res=0;
	for(int i=1;i<=n;i++)res=max(res,vs[i]);
	cout<<res<<endl;
}